package com.coffee.admin.filter;

import com.coffee.core.entity.PassToken;
import com.coffee.core.entity.SiteContextThreadLocal;
import com.coffee.core.util.WebUtil;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;

@Order(2)
@WebFilter(filterName = "siteContentFilter", urlPatterns = "/*")
public class SiteContentFilter implements Filter {


    private final static Logger LOG = LoggerFactory.getLogger(SiteContentFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException,
            ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        LOG.info(req.getRequestURI());
        //初始化
        res.addHeader("Access-Control-Allow-Credentials", "true");
        res.addHeader("Access-Control-Allow-Origin", "*");
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        res.addHeader("Access-Control-Allow-Headers",
                "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,token");
        String stoken= WebUtil.getCookieValue(req, "stoken");
        PassToken pass=new PassToken();
        pass.setStoken(stoken);
        SiteContextThreadLocal.set(pass);
        chain.doFilter(new SiteContentFilter.SiteContentHttpServletRequestWrapper(req), response);
    }

    @Override
    public void destroy() {

    }

    public class SiteContentHttpServletRequestWrapper extends HttpServletRequestWrapper {
        public final byte[] body;

        @SuppressWarnings("WeakerAccess")
        public SiteContentHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            body = ReadAsChars2(request).getBytes(Charset.forName("UTF-8"));
        }


        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {


            final ByteArrayInputStream bais = new ByteArrayInputStream(body);

            return new ServletInputStream() {

                @Override
                public int read() throws IOException {
                    return bais.read();
                }

                @Override
                public boolean isFinished() {
                    return false;
                }

                @Override
                public boolean isReady() {
                    return false;
                }

                @Override
                public void setReadListener(ReadListener readListener) {

                }
            };
        }

        @Override
        public String getParameter(String name) {
            return StringEscapeUtils.escapeHtml4(super.getParameter(name));
        }

        public String ReadAsChars2(ServletRequest request)
        {
            InputStream is = null;
            StringBuilder sb = new StringBuilder();
            try
            {
                is = request.getInputStream();

                byte[] b = new byte[4096];
                for (int n; (n = is.read(b)) != -1;)
                {
                    sb.append(new String(b, 0, n));
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            finally
            {
                if (null != is)
                {
                    try
                    {
                        is.close();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            return sb.toString();
        }

    }



}
